import type { EChartsOption } from 'echarts'
import type { Ref } from 'vue'
import type BeEcharts from './BeEcharts.vue'
import { ref, computed, nextTick, watch, onBeforeUnmount, onMounted } from 'vue'
import echarts from './echarts'

type EchartsUIType = typeof BeEcharts | undefined
type EchartsThemeType = 'dark' | 'light' | null

/**
 * 防抖函数：避免高频 resize 事件频繁触发图表重绘
 */
const debounce = (fn: () => void, delay: number) => {
  let timer: ReturnType<typeof setTimeout> | null = null
  return () => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(fn, delay)
  }
}

/**
 * 封装 ECharts 使用逻辑
 * @param chartRef - 图表组件的 ref
 */
const useEcharts = (chartRef: Ref<EchartsUIType>) => {
  const isDark = ref(false) // 可替换为你项目中的主题状态管理
  let chartInstance: echarts.ECharts | null = null // ECharts 实例
  let cacheOptions: EChartsOption = {} // 缓存的配置项

  /**
   * 根据当前主题动态返回附加配置（如背景色）
   */
  const getOptions = computed((): EChartsOption => {
    return isDark.value ? { backgroundColor: 'transparent' } : {}
  })

  /**
   * 初始化图表实例
   * @param theme - 可选主题（暗黑/明亮）
   */
  const initChartInstance = (theme?: EchartsThemeType): echarts.ECharts | undefined => {
    const el = chartRef.value?.$el
    if (!el) return
    chartInstance = echarts.init(el, theme ?? (isDark.value ? 'dark' : null))
    return chartInstance
  }

  /**
   * 渲染图表（自动处理主题/防止容器未就绪等问题）
   * @param options - 图表配置项
   * @param clear - 是否清除上一次配置（默认为 true）
   */
  const renderEcharts = async (options: EChartsOption, clear = true): Promise<echarts.ECharts | null> => {
    cacheOptions = options // 缓存当前配置
    const mergedOptions = {
      ...options,
      ...getOptions.value
    }

    // 如果容器尚未渲染（常出现在 tab 或 lazy-load 中），等待容器挂载完成
    if (chartRef.value?.offsetHeight === 0) {
      await new Promise((resolve) => setTimeout(resolve, 30))
      return await renderEcharts(mergedOptions, clear) // 递归重试
    }

    // 等待 Vue DOM 更新完成
    await nextTick()

    // 等待一帧时间（避免容器尺寸仍未更新完成）
    await new Promise((resolve) => setTimeout(resolve, 30))

    // 若未初始化图表，则初始化
    if (!chartInstance) {
      const instance = initChartInstance()
      if (!instance) return null
    }

    // 根据传参决定是否清除之前的配置项
    if (clear) chartInstance?.clear()

    // 设置新的配置项
    chartInstance?.setOption(mergedOptions)

    return chartInstance
  }

  /**
   * 图表容器尺寸变化时自动 resize
   */
  const resize = () => {
    chartInstance?.resize({
      animation: {
        duration: 300,
        easing: 'quadraticIn' // 缓动函数
      }
    })
  }

  /**
   * 防抖处理 resize 事件
   */
  const resizeHandler = debounce(resize, 200)

  /**
   * 窗口尺寸变化时，触发图表重绘
   */
  const handleWindowResize = () => {
    resizeHandler()
  }

  let resizeObserver: ResizeObserver | null = null

  /**
   * 生命周期：组件挂载时设置 ResizeObserver 和 resize 监听
   */
  onMounted(() => {
    const el = chartRef.value?.$el
    if (el) {
      // 使用 ResizeObserver 监听容器尺寸变化
      resizeObserver = new ResizeObserver(() => {
        resizeHandler()
      })
      resizeObserver.observe(el)
    }

    // 同时监听窗口大小变化
    window.addEventListener('resize', handleWindowResize)
  })

  /**
   * 生命周期：组件卸载时清理资源
   */
  onBeforeUnmount(() => {
    chartInstance?.dispose()
    chartInstance = null
    resizeObserver?.disconnect()
    resizeObserver = null
    window.removeEventListener('resize', handleWindowResize)
  })

  /**
   * 监听主题变化，自动重新初始化图表并重新渲染
   */
  watch(isDark, async () => {
    if (chartInstance) {
      chartInstance.dispose() // 销毁旧实例
      initChartInstance() // 创建新实例
      await renderEcharts(cacheOptions) // 重新渲染
      resize() // 触发自适应
    }
  })

  return {
    renderEcharts, // 渲染方法
    resize, // 手动 resize
    getChartInstance: () => chartInstance // 获取原始 ECharts 实例
  }
}

export { useEcharts }
export type { EchartsUIType }
